package com.ruicar.afs.jobadmin.controller;

import com.ruicar.afs.cloud.common.core.util.IResponse;
import com.ruicar.afs.cloud.common.job.constant.JobConstant;
import com.ruicar.afs.jobadmin.core.conf.JobAdminConfig;
import com.ruicar.afs.jobadmin.core.util.JacksonUtil;
import com.ruicar.afs.cloud.common.job.core.biz.AdminBiz;
import com.ruicar.afs.cloud.common.job.core.biz.model.HandleCallbackParam;
import com.ruicar.afs.cloud.common.job.core.biz.model.RegistryParam;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * The type JobApiController
 * <p>Description: </p>
 *
 * @author Fzero
 * @version 1.0
 * @date Created on 2020.06.13 14:17:12
 * @since 1.0
 */
@Controller
@RequestMapping("/api")
public class JobApiController {

    /**
     * Admin biz
     * <p>Description: </p>
     */
    @Resource
    private AdminBiz adminBiz;


    // ---------------------- base ----------------------

    /**
     * Valid access token *
     *
     * @param request request
     */
    private void validAccessToken(HttpServletRequest request) {
        if (JobAdminConfig.getAdminConfig().getAccessToken() != null
                && JobAdminConfig.getAdminConfig().getAccessToken().trim().length() > 0
                && !JobAdminConfig.getAdminConfig().getAccessToken().equals(request.getHeader(JobConstant.JOB_ACCESS_TOKEN))) {
            throw new RuntimeException("The access token is wrong.");
        }
    }

    /**
     * Parse param object
     *
     * @param data             data
     * @param parametrized     parametrized
     * @param parameterClasses parameter classes
     * @return the object
     */
    private Object parseParam(String data, Class<?> parametrized, Class<?>... parameterClasses) {
        Object param = null;
        try {
            if (parameterClasses != null) {
                param = JacksonUtil.readValue(data, parametrized, parameterClasses);
            } else {
                param = JacksonUtil.readValue(data, parametrized);
            }
        } catch (Exception e) {
        }
        if (param == null) {
            throw new RuntimeException("The request data invalid.");
        }
        return param;
    }

    // ---------------------- admin biz ----------------------

    /**
     * Callback response
     *
     * @param request request
     * @param data    data
     * @return the response
     */
    @RequestMapping("/callback")
    @ResponseBody
    public IResponse<String> callback(HttpServletRequest request, @RequestBody(required = false) String data) {
        // valid
        validAccessToken(request);

        // param
        List<HandleCallbackParam> callbackParamList = (List<HandleCallbackParam>) parseParam(data, List.class, HandleCallbackParam.class);

        // invoke
        return IResponse.success(adminBiz.callback(callbackParamList));
    }


    /**
     * Registry response
     *
     * @param request request
     * @param data    data
     * @return the response
     */
    @RequestMapping("/registry")
    @ResponseBody
    public IResponse<String> registry(HttpServletRequest request, @RequestBody(required = false) String data) {
        // valid
        validAccessToken(request);

        // param
        RegistryParam registryParam = (RegistryParam) parseParam(data, RegistryParam.class);

        // invoke
        return IResponse.success(adminBiz.registry(registryParam));
    }

    /**
     * Registry remove response
     *
     * @param request request
     * @param data    data
     * @return the response
     */
    @RequestMapping("/registryRemove")
    @ResponseBody
    public IResponse<String> registryRemove(HttpServletRequest request, @RequestBody(required = false) String data) {
        // valid
        validAccessToken(request);

        // param
        RegistryParam registryParam = (RegistryParam) parseParam(data, RegistryParam.class);

        // invoke
        return IResponse.success(adminBiz.registryRemove(registryParam));
    }

    // ---------------------- job biz ----------------------

}
